package com.glsc.ngateway.platform.config;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.utils.JsonTool;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class TrimHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private static Logger logger = LoggerFactory.getLogger(TrimHttpServletRequestWrapper.class);

    private Map<String , String[]> params = new HashMap<>();


    public TrimHttpServletRequestWrapper(HttpServletRequest request) {
        //将request交给父类，以便于调用对应方法的时候，将其输出
        super(request);

        //将参数表，赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
        this.modifyParameterValues();

    }

    /**
     * 重写getInputStream方法  post类型的请求参数必须通过流才能获取到值
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        //非json类型，直接返回
        if (super.getHeader(HttpHeaders.CONTENT_TYPE) == null || !super.getHeader(HttpHeaders.CONTENT_TYPE).contains(MediaType.APPLICATION_JSON_VALUE)) {
            return super.getInputStream();
        }

        //为空，直接返回
        String json = IOUtils.toString(super.getInputStream(), StandardCharsets.UTF_8.name());
        if (!StringUtils.hasLength(json)) {
            return super.getInputStream();
        }

        try {
            JSONObject jsonObject = JSONObject.parseObject(json);

            ByteArrayInputStream bis = new ByteArrayInputStream(JsonTool.jsonTrim(jsonObject).toString().getBytes(StandardCharsets.UTF_8));
            return new MyServletInputStream(bis);
        } catch (Exception e) {

            try {
                JSONArray jsonObject = JSONObject.parseArray(json);
                ByteArrayInputStream bis = new ByteArrayInputStream(JsonTool.jsonTrimArray(jsonObject).toString().getBytes(StandardCharsets.UTF_8));
                return new MyServletInputStream(bis);
            } catch (Exception e2) {
                logger.error("json字符串去除空格时异常", e2);
                return super.getInputStream();
            }

        }
    }

    /**
     * 将parameter的值去除空格后重写回去
     */
    public void modifyParameterValues() {
        Set<String> set =params.keySet();
        for (String key : set) {
            String[] values = params.get(key);
            for (int i = 0; i < values.length; i++) {
                values[i] = values[i].trim();
            }
            params.put(key, values);
        }
    }
    /**
     * 重写getParameter 参数从当前类中的map获取
     */
    @Override
    public String getParameter(String name) {
        String[]values = params.get(name);
        if(values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }
    /**
     * 重写getParameterValues
     */
    @Override
    public String[] getParameterValues(String name) {//同上
        return params.get(name);
    }

    class MyServletInputStream extends ServletInputStream {
        private ByteArrayInputStream bis;
        public MyServletInputStream(ByteArrayInputStream bis){
            this.bis=bis;
        }
        @Override
        public boolean isFinished() {
            return true;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener listener) {

        }
        @Override
        public int read() {
            return bis.read();
        }
    }

}
